home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / ms_dos / dsort / dstmain.pre < prev    next >
Encoding:
Text File  |  1993-07-08  |  41.9 KB  |  1,291 lines

  1.     page    96,132
  2. ;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
  3. ;§                                                                          §
  4. ;§              ディレクトリエントリ  ソート  ユーティリティ                §
  5. ;§                                                                          §
  6. ;§                                     DSORT.EXE  Ver1.30    §
  7. ;§                                                                          §
  8. ;§              Copyright (C) by 福地 邦雄 1991-1992. All rights reserved.  §
  9. ;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
  10.     .MODEL  SMALL,C
  11. ;
  12.     DPB struc
  13. drivenumber     db      ?       ;ドライブ番号
  14. unitnumber      db      ?       ;ユニット番号
  15. sectorlength    dw      ?       ;セクタ長
  16. sectorperalloc  db      ?       ;1クラスタ当たりのセクタ数-1
  17. shiftcount      db      ?       ;1クラスタ当たりのセクタ数の2のべき乗
  18. reservedsector  dw      ?       ;先頭のリザーブセクタ数
  19. numberoffat     db      ?       ;FAT数
  20. directoryentry  dw      ?       ;ルートディレクトリのエントリ数
  21. datastartsector dw      ?       ;データ領域開始セクタ番号
  22. datasector      dw      ?       ;最大クラスタ番号(全クラスタ数+1)
  23. fatsector       dw      ?       ;1FAT当たりのセクタ数
  24. directorystart  dw      ?       ;ディレクトリ領域開始セクタ番号
  25. deviceheader    dd      ?       ;デバイスヘッダへのポインタ
  26. mediadescriptor db      ?       ;メディアディスクリプタ
  27. diskchange      db      ?       ;ディスクの交換可能属性
  28. tonextdpb       dd      ?       ;次のDPBへのポインタ
  29. currentcluster  dw      ?       ;カレントクラスタ
  30. reserved        db  3 dup(?)    ;リザーブ
  31.     DPB ends
  32. ;
  33.     DPB3 struc
  34. DPB3reserv      db  15 DUP(?)   ;ドライブ番号~最大クラスタ番号
  35. D3fatsector       db      ?       ;1FAT当たりのセクタ数
  36. D3directorystart  dw      ?       ;ディレクトリ領域開始セクタ番号
  37. D3deviceheader    dd      ?       ;デバイスヘッダへのポインタ
  38. D3mediadescriptor db      ?       ;メディアディスクリプタ
  39. D3diskchange      db      ?       ;ディスクの交換可能属性
  40. D3tonextdpb       dd      ?       ;次のDPBへのポインタ
  41. D3currentcluster  dw      ?       ;カレントクラスタ
  42. D3reserved        dd      ?       ;リザーブ
  43.     DPB3 ends
  44. ;
  45.     DEVHEAD struc
  46. nextdevice      dd      ?       ; 次のデバイスヘッダへのポインタ
  47. deviceattr      dw      ?       ; デバイス属性
  48. strategy        dw      ?       ; ストラテジエントリオフセット
  49. intrentry       dw      ?       ; 割り込みエントリオフセット
  50. devicename      db  8 dup(?)    ; デバイス名/ドライブ数
  51.     DEVHEAD ends
  52. ;
  53.     DSKPACKET   struc
  54. sectornum       dd      ?       ; 32bitセクタ番号
  55. rwcount         dw      ?       ; READ/WRITEセクタ数
  56. dskbuffer       dd      ?       ; バッファアドレス
  57.     DSKPACKET   ends
  58. ;
  59. YES     equ     1
  60. NO      equ     0
  61. OS2     equ     -1
  62. FAT12   equ     0ff7h
  63. FAT16   equ     0fff7h
  64. SECTOR32    equ 0000000000000010B
  65. direntrysize    equ 20h
  66. ;
  67.     extrn   sweep:word,sortexec:word,recursive:word,dirgather:word
  68.     extrn   dta:dword,srchname:dword,namebuff:dword,namebuffsiz:word
  69.     extrn   dirtype:word,fattype:word,attribute:word,clustcount:word
  70.     extrn   driveno:word,clustsize:word
  71.     extrn   fatbuff:word,dirbuff:word,sortbuff:word,sortcount:word
  72.     extrn   drvinf:byte,clustsect:word,sectcount:word,fatdrive:word
  73.     extrn   sortfuncs:word,subchain:word,wildcard:byte,pathbuff:byte
  74.     extrn   usagemsg:byte,entrycount:word,movecount:word,subsearch:word
  75.     extrn   procs:byte,dirover:byte
  76.     extrn   bothmsg:byte,sortmsg:byte,movemsg:byte,nothmsg:byte
  77.     extrn   errorno:word
  78. ;
  79.     extrn   dos4:word,sect32:word,diskaccs:byte
  80. ;
  81.     extrn   getargs:near,options:near,usageout:near,abort:near,dosstdout:near
  82.     extrn   dirlist:near,dirfind:near,strcopywild:near
  83.     extrn   dosallocx:near,dirqsort:near,inttoasc0:near
  84. ;
  85.     PUBLIC  main,sortproc,getdirinfo,getdpb,readdirectory,readrootdir,readfat
  86.     PUBLIC  getfat12chain,getfat16chain,readsubdir,selection,remainsweep
  87.     PUBLIC  copyback,filldeleted,writerootdirectory,writesubdirectory
  88.     PUBLIC  dspdirname,dspmsgend,altint23h,critical,breakflag,orgint23h
  89. ;
  90.     .code
  91. ;
  92. ;------------------------------------------------------------------------------
  93. ;   書き込み時のCtrl+C押下によるディレクトリ破壊を防ぐ処理のワーク
  94. ;------------------------------------------------------------------------------
  95. ;
  96. critical    dw  NO
  97. breakflag   dw  NO
  98. orgint23h   dd  0
  99. prgname     db  'DirSort',0     ; これは別に意味なし
  100. ;
  101. ;------------------------------------------------------------------------------
  102. ;
  103. ;   main
  104. ;       ディレクトリエントリソートユーティリティ メインプログラム
  105. ;
  106. ;   dsort   <options>   directory name
  107. ;
  108. ;   IN      ds & es PSP セグメント
  109. ;   OUT     ?
  110. ;
  111. ;------------------------------------------------------------------------------
  112. ;
  113. main        proc    near
  114. ;
  115.     call    getargs                 ; コマンド行パラメータを引き数リストに変換
  116.     @if (zf,on)
  117.         jmp     usageout            ; 引き数なしの時はヘルプメッセージ
  118.     @ifend
  119.     push    ax
  120.     mov     ax,_data                ; DS 設定
  121.     mov     ds,ax
  122. ;
  123.     mov     ah,30h                  ; DOS バージョンチェック
  124.     int     21h
  125.     @if (al,>=,4),S                 ; 4.00以上OS/2互換BOX未満ならフラグセット
  126.         @if (al,<,10),S
  127.             mov     dos4,YES
  128.         @else
  129.             mov     dos4,OS2
  130.         @ifend
  131.     @else
  132.         mov     dos4,NO
  133.     @ifend
  134. ;
  135.     mov     ax,1000h                ; ディレクトリ名バッファの獲得
  136.     xor     dx,dx                   ; 4KB
  137.     call    dosallocx
  138.     mov     word ptr namebuff+2,ax
  139. ;
  140.     mov     ax,3523h                ; Ctrl+C ベクタ取得
  141.     int     21h
  142.     mov     word ptr cs:orgint23h,bx
  143.     mov     word ptr cs:orgint23h+2,es
  144.     mov     bx,ds                   ; DS セーブ
  145.     mov     es,bx
  146.     mov     ax,2523h                ; Ctrl+C ベクタ置き換え
  147.     mov     dx,offset altint23h     ;
  148.     mov     bx,cs
  149.     mov     ds,bx
  150.     int     21h
  151.     mov     bx,es                   ; DS リストア
  152.     mov     ds,bx
  153.     pop     ax
  154. ;
  155.     call    options                 ; 引き数評価&対象ディレクトリリスト作成
  156.     @if (sortexec,/=,NO),or,(sweep,/=,NO)
  157.         @if (recursive,=,YES)       ; 再帰呼び出しをおこなうか?
  158.             mov     es,word ptr namebuff+2
  159.             mov     bx,800h         ; ディレクトリ名バッファのサイズ変更
  160.             mov     ah,4ah          ; 32KB
  161.             int     21h
  162.             @if (cf,off)
  163.                 add     namebuffsiz,7000h
  164.             @ifend
  165.         @ifend
  166.         push    namebuffsiz         ; パラメータセット
  167.         push    word ptr namebuff
  168.         push    word ptr namebuff+2
  169.         xor     ax,ax
  170.         push    ax
  171.         call    sortproc            ; ディレクトリソート実行
  172.     @ifend
  173. ;
  174.     mov     ax,2523h                ; Ctrl+C ベクタ復元
  175.     lds     dx,cs:orgint23h
  176.     int     21h
  177. ;
  178.     mov     ah,0dh              ; ディスクバッファ リセット
  179.     int     21h
  180. ;
  181.     mov     ax,4c00h                ; プログラム終了
  182.     int     21h
  183. ;
  184. main        endp
  185. ;
  186. ;------------------------------------------------------------------------------
  187. ;
  188. ;   sortproc
  189. ;       ディレクトリソートを実行する
  190. ;
  191. ;   TYPE    near call
  192. ;   IN      sp+2:ディレクトリ名リストアドレス
  193. ;           sp+6:ディレクトリ名バッファの空き領域の先頭
  194. ;           sp+8:ディレクトリ名バッファの空き領域サイズ
  195. ;   OUT     なし
  196. ;   保存レジスタ ds
  197. ;
  198. ;------------------------------------------------------------------------------
  199. ;
  200. sortproc    proc    near    curnameoff,curnameseg,freenameoff,freenamesiz
  201. ;
  202.     mov     di,curnameoff
  203.     mov     es,curnameseg
  204.     @do until
  205.         mov     entrycount,0        ; 処理したエントリのカウンタを初期化
  206.         mov     sortcount,0
  207.         mov     movecount,0
  208.         mov     ah,0dh              ; ディスクバッファ リセット
  209.         int     21h
  210. ;
  211.         call    getdirinfo          ; ディレクトリ情報獲得
  212.         @if (zf,on),L
  213.             mov     di,curnameoff   ; ディレクトリ名表示
  214.             mov     es,curnameseg
  215.             call    dspdirname
  216.             call    readdirectory   ; ディレクトリ読み込み
  217.             @if (zf,on)
  218.                 @if (sortexec,=,YES),S
  219.                     call    selection   ; ソート対象エントリ取り出し
  220.                     @if (ax,>,1)
  221.                         push    ds
  222.                         mov     ax,ds
  223.                         mov     es,ax
  224.                         mov     ax,offset sortfuncs
  225.                         push    ax
  226.                         push    sortcount
  227.                         push    sortbuff
  228.                         call    dirqsort    ; クイックソート
  229.                         pop ds
  230.                     @ifend
  231.                     @if (sweep,=,YES)
  232.                         call    remainsweep ; ソート対象外エントリを掻き集める
  233.                     @ifend
  234.                     call    copyback    ; ソートしたエントリを戻す
  235.                 @else
  236.                     call    predelete
  237.                     call    remainsweep
  238.                 @ifend
  239.                 call    filldeleted     ; 削除エントリの情報をクリアする
  240.                 mov     cs:critical,YES ; クリティカルセクション開始
  241.                 @if (dirtype,=,0),S
  242.                     call    writerootdirectory  ; ルートディレクトリ書き込み
  243.                 @else
  244.                     call    writesubdirectory   ; サブディレクトリ書き込み
  245.                 @ifend
  246.                 mov     es,dirbuff              ; ディレクトリバッファの開放
  247.                 mov     ah,49h
  248.                 int     21h
  249.                 call    dspmsgend       ; 終了メッセージ表示
  250.                 mov     cs:critical,NO  ; クリティカルセクション終了
  251.                 @if (cs:breakflag,=,YES)    ; Ctrl+Cが押下されたので終了
  252.                     mov     errorno,-1
  253.                     xor     cx,cx
  254.                     xor     dx,dx
  255.                     jmp     abort
  256.                 @ifend
  257.             @ifend
  258.             @if (recursive,=,YES)   ; 再帰呼び出し
  259.                 mov     ah,0dh      ; ディスクバッファ リセット
  260.                 int     21h
  261. ;
  262.                 mov     subsearch,YES   ;
  263.                 mov     di,curnameoff   ; サブディレクトリのリスト獲得
  264.                 mov     es,curnameseg
  265.                 call    strcopywild
  266.                 mov     word ptr srchname,di
  267.                 mov     word ptr srchname+2,es
  268.                 call    dirlist
  269.                 mov     ax,word ptr namebuff
  270.                 @if (ax,/=,freenameoff) ; サブディレクトリ有りの時
  271.                     push    namebuffsiz
  272.                     push    ax
  273.                     push    word ptr namebuff+2
  274.                     push    freenameoff
  275.                     call    sortproc    ; ディレクトリソート再帰実行
  276.                 @ifend
  277.                 mov     si,freenameoff  ; 各ワーク情報を再帰実行から戻す
  278.                 mov     es,freenamesiz
  279.                 mov     namebuffsiz,es
  280.                 mov     word ptr namebuff,si
  281.                 mov     es,curnameseg
  282.                 mov     word ptr es:[si],0
  283.                 mov     subsearch,NO    ;
  284.             @ifend
  285.         @ifend
  286.         mov     di,curnameoff       ; 次の対象ディレクトリへ
  287.         mov     es,curnameseg
  288.         cld
  289.         xor     ax,ax
  290.         mov     cx,-1
  291.       repne scasb
  292.         mov     curnameoff,di
  293.     @doend (byte ptr es:[di],=,0),L ; ディレクトリリストの終了か?
  294. ;
  295.     ret     8
  296. ;
  297. sortproc    endp
  298. ;
  299. ;------------------------------------------------------------------------------
  300. ;
  301. ;   getdirinfo
  302. ;       ディレクトリ及びその所属するドライブの情報を獲得する
  303. ;
  304. ;   TYPE    near call
  305. ;   IN      ds:di = ディレクトリ名
  306. ;   OUT     drvinf = DPBのコピー  その他 ディレクトリ情報
  307. ;   保存レジスタ bx,cx,dx,si,di,bp,ds,es
  308. ;
  309. ;------------------------------------------------------------------------------
  310. ;
  311. getdirinfo  proc    near
  312. ;
  313.     call    dirfind
  314.     @if (zf,on)
  315.         mov     dirtype,ax          ; ディレクトリタイプ ルート/サブ
  316.         mov     subchain,ax         ; FATチェインの先頭
  317.         mov     driveno,dx          ; ドライブ番号
  318.         dec     driveno
  319. ;
  320.         mov     di,offset drvinf    ; Drive Parameter Block 取得
  321.         call    getdpb
  322.         @if (zf,on)
  323.             @if (drvinf.datasector,<=,4086),S    ; 12bitFAT/16bitFAT
  324.                 mov     fattype,FAT12            ;   v1.00バグ '='が無かった
  325.             @else
  326.                 mov     fattype,FAT16
  327.             @ifend
  328.             xor     ax,ax
  329.             mov     al,drvinf.sectorperalloc
  330.             inc     ax
  331.             mov     clustsect,ax        ; 1クラスタ当たりのセクタ数
  332.             mul     drvinf.sectorlength
  333.             mov     clustsize,ax        ; 1クラスタのバイトサイズ
  334.             les     bx,drvinf.deviceheader ; デバイスドライバ属性テスト
  335.             @if (dos4,=,OS2),or,(es:[bx].deviceattr,on,SECTOR32),S
  336.                 mov     sect32,YES      ; 32bitセクタ番号サポート
  337.             @else
  338.                 mov     sect32,NO
  339.             @ifend
  340.             xor     ax,ax
  341.         @ifend
  342.     @ifend
  343.     ret
  344. ;
  345. getdirinfo  endp
  346. ;
  347. ;------------------------------------------------------------------------------
  348. ;
  349. ;   getdpb
  350. ;       ドライブパラメータブロックをコピーする
  351. ;
  352. ;   TYPE    near call
  353. ;   IN      dl = ドライブ番号 A:1 B:2 ...
  354. ;           ds:di = drive parameter block をコピーする領域のアドレス
  355. ;           ds:dos4 DOS V4.xx以上フラグ
  356. ;   OUT     ax = 完了コード
  357. ;   保存レジスタ bx,cx,dx,si,di,bp,ds,es
  358. ;
  359. ;------------------------------------------------------------------------------
  360. ;
  361. getdpb      proc    near    uses bx cx si di ds es
  362. ;
  363.     cld
  364.     mov     ax,ds                   ; DS セーブ
  365.     mov     es,ax
  366.     mov     ah,32h                  ; DPBアドレス取得 非公開
  367.     int     21h
  368.     @if (al,=,0),S
  369.         mov     cx,11h                  ; DPB コピー 34バイト
  370.         mov     si,bx
  371.         push    di
  372.       rep   movsw                       ; DPB コピー
  373.         pop     di
  374.         @if (es:dos4,/=,YES) ; DOS V3.xx以下のときFATセクタ数が1バイトなので
  375.             lea     si,[bx].D3directorystart ; 後ろに1バイト移動コピーする
  376.             lea     di,[di].directorystart
  377.             mov     cx,8
  378.           rep   movsw
  379.             and     es:drvinf.fatsector,0FFH ; 移動後のゴミをクリア
  380.         @ifend
  381.         xor     ax,ax
  382.     @else
  383.         test    ax,ax
  384.     @ifend
  385.     ret
  386. ;
  387. getdpb      endp
  388. ;
  389. ;------------------------------------------------------------------------------
  390. ;
  391. ;   readdirectory
  392. ;       ディレクトリを読み込む
  393. ;
  394. ;   TYPE    near call
  395. ;   IN      dirtype,driveno,drvinf構造体,fatdrive
  396. ;   OUT     ax = 完了コード     entrycount,clustcount
  397. ;   保存レジスタ bx,cx,dx,di,bp,ds
  398. ;
  399. ;------------------------------------------------------------------------------
  400. ;
  401. readdirectory   proc    near
  402. ;
  403.     @if (dirtype,=,0),S             ; ルートディレクトリ
  404.         mov     ax,drvinf.directoryentry
  405.         mov     entrycount,ax       ; ディレクトリエントリ数 格納
  406.         call    readrootdir
  407.     @else
  408.         mov     ax,driveno          ; サブディレクトリ
  409.         @if (ax,/=,fatdrive)        ; 読み込み済FATと違うドライブ名の時
  410.             call    readfat         ; FAT読み込み
  411.         @ifend
  412. ;
  413.         cld                         ; サブディレクトリのクラスタチェインを獲得
  414.         mov     di,offset subchain
  415.         mov     es,fatbuff
  416.         @if (fattype,=,FAT12),S
  417.             call    getfat12chain
  418.         @else
  419.             call    getfat16chain
  420.         @ifend
  421.         @if (dx,>=,1026),S
  422.             mov     ah,9            ; ディレクトリサイズオーバー表示
  423.             mov     dx,offset dirover
  424.             int     21h
  425.             mov     ax,-1
  426.         @else
  427.             mov     clustcount,dx   ; サブディレクトリのクラスタ数を設定
  428.             mov     ax,dx
  429.             mul     clustsize
  430.             mov     cx,32           ; ディレクトリエントリ数 計算 格納
  431.             div     cx
  432.             mov     entrycount,ax
  433.             call    readsubdir      ; サブディレクトリ読み込み
  434.         @ifend
  435.     @ifend
  436. rdirerror:
  437.     test    ax,ax
  438.     ret
  439. ;
  440. readdirectory   endp
  441. ;
  442. ;------------------------------------------------------------------------------
  443. ;
  444. ;   readrootdir
  445. ;       ルートディレクトリの内容をメモリに読み込む
  446. ;
  447. ;   TYPE    near call
  448. ;   IN      drive parameter block 領域
  449. ;   OUT     dirbuff = 読み込んだディレクトリのセグメントアドレス
  450. ;   保存レジスタ bp,ds,es
  451. ;
  452. ;------------------------------------------------------------------------------
  453. ;
  454. readrootdir     proc    near
  455.     local rdsect:word,dirlen:word,buffseg:word,maxrdsect:word
  456. ;
  457.     mov     ax,drvinf.datastartsector ; ディレクトリサイズ計算とメモリ獲得
  458.     sub     ax,drvinf.directorystart
  459.     mov     sectcount,ax
  460.     mul     drvinf.sectorlength
  461.     call    dosallocx
  462.     mov     dirbuff,ax
  463. ;
  464.     mov     ax,drvinf.directorystart ; ルートディレクトリ読み込み
  465.     mov     rdsect,ax               ; 読み込み開始セクタ番号
  466.     mov     ax,sectcount
  467.     mov     dirlen,ax               ; 残りディレクトリセクタ数
  468.     mov     ax,dirbuff
  469.     mov     buffseg,ax              ; 読み込みバッファセグメント
  470.     mov     dx,1
  471.     xor     ax,ax
  472.     div     drvinf.sectorlength
  473.     mov     maxrdsect,ax            ; 64KB当たりのセクタ数
  474.     @do while,(dirlen,/=,0)         ; 読み込みループ 残りセクタ数0まで
  475.         mov     ax,driveno
  476.         mov     cx,maxrdsect
  477.         @if (cx,<=,dirlen),S        ; 残りセクタ数が64KB以上なら
  478.             sub     dirlen,cx       ; 残りセクタ数を更新
  479.         @else                       ; 64KB未満なら
  480.             xor     cx,cx           ; セクタ数を獲得してワークには0を入れる
  481.             xchg    dirlen,cx
  482.         @ifend
  483.         mov     dx,rdsect           ; 開始セクタ数獲得
  484.         push    bp                  ; 読み込み
  485.         push    ds
  486.         @if (sect32,=,NO),S         ; 従来の16bitセクタ番号
  487.             xor     bx,bx
  488.             mov     ds,buffseg
  489.         @else                       ; 新規の32bitセクタ番号
  490.             mov     bx,offset diskaccs
  491.             mov     word ptr [bx].sectornum,dx
  492.             mov     word ptr [bx].sectornum+2,0
  493.             mov     [bx].rwcount,cx
  494.             mov     cx,buffseg
  495.             mov     word ptr [bx].dskbuffer,0
  496.             mov     word ptr [bx].dskbuffer+2,cx
  497.             mov     cx,-1
  498.         @ifend
  499.         int     25h
  500.         @if (cf,on)
  501.             xor     cx,cx
  502.             xor     dx,dx
  503.             jmp     abort
  504.         @ifend
  505.         popf
  506.         pop     ds
  507.         pop     bp
  508. ;
  509.         mov     ax,maxrdsect        ; 読み込み開始セクタ数更新
  510.         add     rdsect,ax
  511.         add     buffseg,1000h       ; 読み込みバッファセグメント更新
  512.     @doend
  513.     xor     ax,ax
  514.     ret
  515. ;
  516. readrootdir     endp
  517. ;
  518. ;------------------------------------------------------------------------------
  519. ;
  520. ;   readfat
  521. ;       FATを読み込むための領域を獲得し、FATを読み込む
  522. ;
  523. ;   TYPE    near call
  524. ;   IN      drive parameter block 領域
  525. ;   OUT     fatbuff = 読み込んだFATのセグメントアドレス
  526. ;   保存レジスタ bp,ds,es
  527. ;
  528. ;------------------------------------------------------------------------------
  529. ;
  530. readfat     proc    near
  531.     local rdsect:word,fatlen:word,buffseg:word,maxrdsect:word
  532. ;
  533.     @if (fatdrive,/=,-1)            ; 既に別のFATを読み込み済の時、解放する
  534.         mov     ah,49h              ; メモリ解放FUNC 未設定のバグ
  535.         mov     es,fatbuff
  536.         int     21h
  537.         mov     fatdrive,-1
  538.         mov     fatbuff,0
  539.     @ifend
  540.     mov     ax,drvinf.fatsector     ; FAT用領域獲得
  541.     mul     drvinf.sectorlength
  542.     call    dosallocx
  543.     mov     fatbuff,ax
  544. ;
  545.     mov     ax,driveno              ; 128KB BIG-FAT対応
  546.     mov     fatdrive,ax
  547.     mov     ax,drvinf.reservedsector ; ワーク設定
  548.     mov     rdsect,ax               ; 読み込み開始セクタ番号
  549.     mov     ax,drvinf.fatsector
  550.     mov     fatlen,ax               ; 残りFATセクタ数
  551.     mov     ax,fatbuff
  552.     mov     buffseg,ax              ; 読み込みバッファセグメント
  553.     mov     dx,1
  554.     xor     ax,ax
  555.     div     drvinf.sectorlength
  556.     mov     maxrdsect,ax            ; 64KB当たりのセクタ数
  557.     @do while,(fatlen,/=,0)         ; FAT読み込みループ 残りセクタ数0まで
  558.         mov     ax,driveno
  559.         mov     cx,maxrdsect
  560.         @if (cx,<=,fatlen),S        ; 残りFATセクタ数が64KB以上なら
  561.             sub     fatlen,cx       ; 残りFATセクタ数を更新
  562.         @else                       ; 64KB未満なら
  563.             xor     cx,cx           ; セクタ数を獲得してワークには0を入れる
  564.             xchg    fatlen,cx
  565.         @ifend
  566.         mov     dx,rdsect           ; 開始セクタ数獲得
  567.         push    bp                  ; FAT読み込み
  568.         push    ds
  569.         @if (sect32,=,NO),S         ; 従来の16bitセクタ番号
  570.             xor     bx,bx
  571.             mov     ds,buffseg
  572.         @else                       ; 新規の32bitセクタ番号
  573.             mov     bx,offset diskaccs
  574.             mov     word ptr [bx].sectornum,dx
  575.             mov     word ptr [bx].sectornum+2,0
  576.             mov     [bx].rwcount,cx
  577.             mov     cx,buffseg
  578.             mov     word ptr [bx].dskbuffer,0
  579.             mov     word ptr [bx].dskbuffer+2,cx
  580.             mov     cx,-1
  581.         @ifend
  582.         int     25h
  583.         @if (cf,on)
  584.             xor     cx,cx
  585.             xor     dx,dx
  586.             jmp     abort
  587.         @ifend
  588.         popf
  589.         pop     ds
  590.         pop     bp
  591. ;
  592.         mov     ax,maxrdsect        ; 読み込み開始セクタ数更新
  593.         add     rdsect,ax
  594.         add     buffseg,1000h       ; 読み込みバッファセグメント更新
  595.     @doend
  596.     ret
  597. ;
  598. readfat     endp
  599. ;
  600. ;------------------------------------------------------------------------------
  601. ;
  602. ;   getfat12chain
  603. ;       12ビットFATのチェインをたどって、配列に書き出す。
  604. ;
  605. ;   TYPE    near call
  606. ;   IN      es:オフセット0= FAT領域
  607. ;           ds:di = FATチェインを書き出す配列、 及びその先頭に最初のクラスタ
  608. ;           番号を格納しておくこと
  609. ;   OUT     dx = チェインの総クラスタ数
  610. ;   保存レジスタ si,bp,ds,es
  611. ;
  612. ;------------------------------------------------------------------------------
  613. ;
  614. getfat12chain   proc    near
  615. ;
  616.     mov     cl,4
  617.     xor     dx,dx
  618.     @do while,(word ptr [di],<,FAT12),and,(dx,<,1026)
  619.         mov     bx,[di]
  620.         mov     ax,bx
  621.         shr     ax,1
  622.         add     bx,ax
  623.         mov     ax,es:[bx]
  624.         @if (word ptr [di],off,1),S
  625.             and     ax,0fffh
  626.         @else
  627.             shr     ax,cl
  628.         @ifend
  629.         lea     di,[di+2]
  630.         mov     [di],ax
  631.         inc     dx
  632.     @doend
  633.     ret
  634. ;
  635. getfat12chain   endp
  636. ;
  637. ;------------------------------------------------------------------------------
  638. ;
  639. ;   getfat16chain
  640. ;       16ビットFATのチェインをたどって、配列に書き出す。
  641. ;
  642. ;   TYPE    near call
  643. ;   IN      es:オフセット0 = FAT領域
  644. ;           ds:di = FATチェインを書き出す配列、 及びその先頭に最初のクラスタ
  645. ;           番号を格納しておくこと
  646. ;   OUT     dx = チェインの総クラスタ数
  647. ;   保存レジスタ cx,bp,ds
  648. ;
  649. ;------------------------------------------------------------------------------
  650. ;
  651. getfat16chain   proc    near
  652. ;
  653.     mov     si,es                   ; 128KB BIG-FAT対応 FAT領域セグメント退避
  654.     xor     dx,dx
  655.     @do while,(word ptr [di],<,FAT16),and,(dx,<,1026)
  656.         mov     bx,[di]
  657.         shl     bx,1
  658.         @if (cf,off),S              ; 最初の64KB
  659.             mov     es,si
  660.         @else                       ; 次の64KB
  661.             lea     ax,[si+1000h]
  662.             mov     es,ax
  663.         @ifend
  664.         mov     ax,es:[bx]          ; FATチェインの獲得
  665.         lea     di,[di+2]
  666.         mov     [di],ax
  667.         inc     dx
  668.     @doend
  669.     ret
  670. ;
  671. getfat16chain   endp
  672. ;
  673. ;------------------------------------------------------------------------------
  674. ;
  675. ;   readsubdir
  676. ;       サブディレクトリを読み込む
  677. ;
  678. ;   TYPE    near call
  679. ;   IN      clustcount ディレクトリのクラスタ数
  680. ;   OUT     dirbuff = 読み込んだディレクトリのセグメントアドレス
  681. ;   保存レジスタ cx,si,bp,ds,es
  682. ;
  683. ;------------------------------------------------------------------------------
  684. ;
  685. readsubdir     proc    near
  686.     local cluster:word,clustseg:word
  687. ;
  688.     mov     dx,clustcount           ; ディレクトリサイズ計算
  689.     mov     cluster,dx
  690.     mov     ax,clustsect
  691.     mul     dx
  692.     mul     drvinf.sectorlength
  693.     call    dosallocx               ; ディレクトリバッファ獲得
  694.     mov     dirbuff,ax
  695.     mov     ax,clustsize
  696.     mov     cl,4
  697.     shr     ax,cl
  698.     mov     clustseg,ax
  699.     xor     bx,bx
  700.     mov     di,offset subchain      ; ディレクトリクラスタチェインの先頭
  701. ;
  702.     @if (sect32,=,NO)
  703.         push    ds
  704.         mov     ax,ds
  705.         mov     es,ax
  706.         mov     ds,dirbuff
  707.         @do until
  708.             mov     ax,es:[di]          ; ディレクトリクラスタ読み込み
  709.             sub     ax,2
  710.             mov     cx,es:clustsect
  711.             mul     cx
  712.             add     ax,es:drvinf.datastartsector
  713.             mov     dx,ax
  714.             mov     ax,es:driveno
  715.             push    bp
  716.             push    di
  717.             int     25h
  718.             @if (cf,on)
  719.                 xor     cx,cx
  720.                 xor     dx,dx
  721.                 jmp     abort
  722.             @ifend
  723.             popf
  724.             pop     di
  725.             pop     bp
  726.             mov     ax,ds
  727.             add     ax,clustseg         ; 次のバッファセグメント
  728.             mov     ds,ax
  729.             lea     di,[di+2]           ; 次のクラスタ
  730.             dec     cluster             ; カウントダウン
  731.         @doend (zf,on)
  732.         pop ds
  733.     @else
  734.         mov     ax,clustsect
  735.         mov     diskaccs.rwcount,ax
  736.         mov     ax,dirbuff
  737.         mov     word ptr diskaccs.dskbuffer,0
  738.         mov     word ptr diskaccs.dskbuffer+2,ax
  739.         @do until
  740.             mov     bx,offset diskaccs
  741.             mov     ax,[di]             ; ディレクトリクラスタ読み込み
  742.             sub     ax,2
  743.             mov     cx,clustsect
  744.             mul     cx
  745.             add     ax,drvinf.datastartsector
  746.             adc     dx,0
  747.             mov     word ptr [bx].sectornum,ax
  748.             mov     word ptr [bx].sectornum+2,dx
  749.             mov     ax,driveno
  750.             mov     cx,-1
  751.             push    bp
  752.             push    di
  753.             int     25h
  754.             @if (cf,on)
  755.                 xor     cx,cx
  756.                 xor     dx,dx
  757.                 jmp     abort
  758.             @ifend
  759.             popf
  760.             pop     di
  761.             pop     bp
  762.             mov     ax,clustseg
  763.             add     word ptr diskaccs.dskbuffer+2,ax  ; 次のバッファセグメント
  764.             lea     di,[di+2]                       ; 次のクラスタ
  765.             dec     cluster                         ; カウントダウン
  766.         @doend (zf,on)
  767.     @ifend
  768.     xor     ax,ax
  769.     ret
  770. ;
  771. readsubdir  endp
  772. ;
  773. ;------------------------------------------------------------------------------
  774. ;
  775. ;   selection
  776. ;       読み込んだディレクトリからattributeで指定されたエントリを選択して
  777. ;       ソートバッファに移動する
  778. ;
  779. ;   TYPE    near call
  780. ;   IN      dirbuff = 読み込んだディレクトリのセグメントアドレス その他
  781. ;   OUT     sortbuff = ソート対象を選択・移動したセグメントアドレス
  782. ;   保存レジスタ bp,ds
  783. ;
  784. ;------------------------------------------------------------------------------
  785. ;
  786. selection   proc    near
  787. ;
  788.     mov     ax,direntrysize         ; ディレクトリサイズからバッファサイズ
  789.     mul     entrycount              ;
  790.     call    dosallocx               ; ソートバッファ獲得
  791.     mov     sortbuff,ax
  792.     mov     es,ax
  793.     mov     bx,attribute            ; 選出属性
  794.     mov     dx,entrycount           ; エントリ数
  795.     mov     si,dirbuff
  796.     @if (dirtype,/=,0)              ; サブディレクトリの時は最初の2つを除外
  797.         sub     dx,2
  798.         lea     si,[si+4]
  799.     @ifend
  800. ;
  801.     push    ds
  802.     cld
  803.     xor     ax,ax
  804.     mov     ds,si
  805.     @do while,(dx,/=,0),and,(byte ptr ds:[0],/=,0)
  806.         @cbegin
  807.         @case (byte ptr ds:[0],=,0e5h),S   ; 削除エントリか?
  808.             mov     byte ptr ds:[0],0      ; 後の処理のために0を書いておく
  809.         @case (byte ptr ds:[0bh],on,bl),S  ; 属性違いか?
  810.         @other                      ; ソートバッファへ移動
  811.             mov     cx,10h
  812.             xor     si,si
  813.             xor     di,di
  814.           rep   movsw
  815.             mov     byte ptr ds:[0],0  ; 移動元に0を書いておく
  816.             @if (byte ptr es:[0],=,5)   ; 名前の頭がE5用のコードなら戻しておく
  817.                 mov     byte ptr es:[0],0e5h
  818.             @ifend
  819.             mov     si,es
  820.             lea     si,[si+2]
  821.             mov     es,si
  822.             inc     ax              ; 移動したエントリ数を加算
  823.         @cend
  824.         mov     si,ds
  825.         lea     si,[si+2]
  826.         mov     ds,si
  827.         dec     dx                  ; カウントダウン
  828.     @doend
  829.     pop     ds
  830.     mov     sortcount,ax            ; 移動したエントリ数を記録
  831.     ret
  832. ;
  833. selection   endp
  834. ;
  835. ;------------------------------------------------------------------------------
  836. ;
  837. ;   predelete
  838. ;       後のremainsweepルーチンのために削除エントリの先頭を00とする
  839. ;
  840. ;   TYPE    near call
  841. ;   IN      entrycount,dirbuff
  842. ;   OUT     なし
  843. ;   保存レジスタ ax,bx,dx,si,bp,ds
  844. ;
  845. ;------------------------------------------------------------------------------
  846. ;
  847. predelete   proc    near
  848. ;
  849.     mov     cx,entrycount
  850.     mov     di,dirbuff
  851.     @do until
  852.         mov     es,di
  853.         @if (byte ptr es:[0],=,0e5h)
  854.             mov     byte ptr es:[0],0
  855.         @ifend
  856.         lea     di,[di+2]
  857.         dec     cx
  858.     @doend (zf,on)
  859.     ret
  860. ;
  861. predelete   endp
  862. ;
  863. ;------------------------------------------------------------------------------
  864. ;
  865. ;   remainsweep
  866. ;       ソート対象外のエントリをディレクトリバッファの先頭に集める
  867. ;
  868. ;   TYPE    near call
  869. ;   IN      entrycount,dirbuff
  870. ;   OUT     movecount
  871. ;   保存レジスタ ax,bp,ds
  872. ;
  873. ;------------------------------------------------------------------------------
  874. ;
  875. remainsweep proc    near
  876. ;
  877.     cld
  878.     push    ds
  879.     xor     bx,bx
  880.     mov     dx,entrycount           ; ディレクトリのエントリサイズ
  881.     mov     ds,dirbuff
  882.     mov     di,ds                   ; 最初の空きエントリ位置取得
  883.     @do while,(byte ptr ds:[0],/=,0),and,(dx,/=,0)
  884.         lea     di,[di+2]
  885.         mov     ds,di
  886.         dec     dx
  887.     @doend
  888.     mov     es,di
  889.     @do until
  890.         mov     di,ds               ; 次の有効エントリ位置取得
  891.         @do while,(byte ptr ds:[0],=,0),and,(dx,/=,0)
  892.             lea     di,[di+2]
  893.             mov     ds,di
  894.             dec     dx
  895.         @doend
  896.         @if (dx,/=,0)               ; 終了でなければエントリを頭へ詰める
  897.             inc     bx
  898.             mov     cx,10h
  899.             xor     si,si
  900.             xor     di,di
  901.           rep   movsw
  902.             mov     byte ptr ds:[0],0 ; 移動元を空きエントリとする
  903.             mov     di,es
  904.             @do while,(byte ptr es:[0],/=,0)  ; 次の空きエントリ位置取得
  905.                 lea     di,[di+2]
  906.                 mov     es,di
  907.             @doend
  908.         @ifend
  909.     @doend (dx,=,0)
  910.     pop     ds
  911.     mov     movecount,bx            ; 移動したエントリ数を記録
  912.     ret
  913. ;
  914. remainsweep endp
  915. ;
  916. ;------------------------------------------------------------------------------
  917. ;
  918. ;   copyback
  919. ;       ソートバッファの内容をディレクトリバッファへ書き戻す
  920. ;
  921. ;   TYPE    near call
  922. ;   IN      sortcount,sortbuff,dirbuff
  923. ;   OUT     dirbuff
  924. ;   保存レジスタ    bx,bp,ds
  925. ;
  926. ;------------------------------------------------------------------------------
  927. ;
  928. copyback    proc    near    uses ds
  929. ;
  930.     cld
  931.     mov     dx,sortcount            ; ソートバッファ上のエントリ数
  932.     mov     es,dirbuff
  933.     mov     ds,sortbuff
  934.     @do while,(dx,/=,0)
  935.         @if (byte ptr es:[0],=,0),S     ; ディレクトリバッファは空きエントリ?
  936.             @if (byte ptr ds:[0],=,0e5h)   ; 名前の頭がE5なら、変換しておく
  937.                 mov     byte ptr ds:[0],05h
  938.             @ifend
  939.             mov     cx,10h          ; コピー
  940.             xor     si,si
  941.             xor     di,di
  942.           rep   movsw
  943.             dec     dx              ; カウントダウン
  944.             mov     si,ds           ; 次のソートバッファエントリへ
  945.             lea     si,[si+2]
  946.             mov     ds,si
  947.         @ifend
  948.         mov     si,es               ; 次のディレクトリバッファエントリへ
  949.         lea     si,[si+2]
  950.         mov     es,si
  951.     @doend
  952. ;
  953.     mov     ax,seg sortbuff         ; ソートバッファの解放
  954.     mov     ds,ax
  955.     mov     es,sortbuff
  956.     mov     ah,49h
  957.     int     21h
  958. ;
  959.     ret
  960. ;
  961. copyback    endp
  962. ;
  963. ;------------------------------------------------------------------------------
  964. ;
  965. ;   filldeleted
  966. ;       ディレクトリ中の削除エントリをクリアする
  967. ;
  968. ;   TYPE    near call
  969. ;   IN      entrycount,dirbuff
  970. ;   OUT     なし
  971. ;   保存レジスタ    bx,bp,ds
  972. ;
  973. ;------------------------------------------------------------------------------
  974. ;
  975. filldeleted proc    near
  976. ;
  977.     cld
  978.     mov     ax,0f6h                 ; 埋め込みデータの設定 
  979.     mov     si,entrycount           ; ディレクトリの最終ポイント取得
  980.     mov     dx,si
  981.     shl     dx,1
  982.     add     dx,dirbuff
  983.     @do until
  984.         sub     dx,2                ; 最終位置から先頭方向へ
  985.         mov     es,dx
  986.         @if (byte ptr es:[0],=,0),S ; 削除エントリ判定
  987.             mov     es:[0],ah       ; 頭1バイト 0orE5
  988.             mov     cx,1fh          ; 残り31バイトをF6で埋める
  989.             mov     di,1
  990.           rep   stosb
  991.         @else                       ; 有効エントリが見つかったので
  992.             mov     ah,0e5h         ; それ以後は頭1バイトをE5に変更
  993.         @ifend
  994.         dec     si
  995.     @doend (si,=,0)                 ; ディレクトリ先頭になるまで
  996.     ret
  997. ;
  998. filldeleted endp
  999. ;
  1000. ;------------------------------------------------------------------------------
  1001. ;
  1002. ;   writerootdirectory
  1003. ;       ルートディレクトリバッファをファイルに書き戻す
  1004. ;
  1005. ;   TYPE    near call
  1006. ;   IN      dirtype,driveno,drvinf構造体,sectcount,clustcount,dirbuff
  1007. ;           clustsect,clustsize,subchain
  1008. ;   OUT     なし
  1009. ;   保存レジスタ
  1010. ;
  1011. ;------------------------------------------------------------------------------
  1012. ;
  1013. writerootdirectory  proc    near
  1014.     local wtsect:word,dirlen:word,buffseg:word,maxwtsect:word
  1015. ;
  1016.     mov     ax,drvinf.directorystart ; ルートディレクトリ書き込み
  1017.     mov     wtsect,ax               ; 書き込み開始セクタ番号
  1018.     mov     ax,sectcount
  1019.     mov     dirlen,ax               ; 残りディレクトリセクタ数
  1020.     mov     ax,dirbuff
  1021.     mov     buffseg,ax              ; 書き込みバッファセグメント
  1022.     mov     dx,1
  1023.     xor     ax,ax
  1024.     div     drvinf.sectorlength
  1025.     mov     maxwtsect,ax            ; 64KB当たりのセクタ数
  1026.     @do while,(dirlen,/=,0)         ; 書き込みループ 残りセクタ数0まで
  1027.         mov     ax,driveno
  1028.         mov     cx,maxwtsect
  1029.         @if (cx,<=,dirlen),S        ; 残りセクタ数が64KB以上なら
  1030.             sub     dirlen,cx       ; 残りセクタ数を更新
  1031.         @else                       ; 64KB未満なら
  1032.             xor     cx,cx           ; セクタ数を獲得してワークには0を入れる
  1033.             xchg    dirlen,cx
  1034.         @ifend
  1035.         mov     dx,wtsect           ; 開始セクタ数獲得
  1036.         push    bp                  ; 書き込み
  1037.         push    ds
  1038.         @if (sect32,=,NO),S         ; 従来の16bitセクタ番号
  1039.             xor     bx,bx
  1040.             mov     ds,buffseg
  1041.         @else                       ; 新規の32bitセクタ番号
  1042.             mov     bx,offset diskaccs
  1043.             mov     word ptr [bx].sectornum,dx
  1044.             mov     word ptr [bx].sectornum+2,0
  1045.             mov     [bx].rwcount,cx
  1046.             mov     cx,buffseg
  1047.             mov     word ptr [bx].dskbuffer,0
  1048.             mov     word ptr [bx].dskbuffer+2,cx
  1049.             mov     cx,-1
  1050.         @ifend
  1051.         int     26h
  1052.         @if (cf,on)
  1053.             xor     cx,cx
  1054.             xor     dx,dx
  1055.             jmp     abort
  1056.         @ifend
  1057.         popf
  1058.         pop     ds
  1059.         pop     bp
  1060. ;
  1061.         mov     ax,maxwtsect        ; 書き込み開始セクタ数更新
  1062.         add     wtsect,ax
  1063.         add     buffseg,1000h       ; 書き込みバッファセグメント更新
  1064.     @doend
  1065.     ret
  1066. ;
  1067. writerootdirectory  endp
  1068. ;
  1069. ;------------------------------------------------------------------------------
  1070. ;
  1071. ;   writesubdirectory
  1072. ;       サブディレクトリバッファをファイルに書き戻す
  1073. ;
  1074. ;   TYPE    near call
  1075. ;   IN      dirtype,driveno,drvinf構造体,sectcount,clustcount,dirbuff
  1076. ;           clustsect,clustsize,subchain
  1077. ;   OUT     なし
  1078. ;   保存レジスタ
  1079. ;
  1080. ;------------------------------------------------------------------------------
  1081. ;
  1082. writesubdirectory  proc    near
  1083.         local cluster:word,clustseg:word
  1084. ;
  1085.     push    ds                  ; サブディレクトリ書き込み
  1086.     mov     ax,clustcount
  1087.     mov     cluster,ax
  1088.     mov     ax,clustsize
  1089.     mov     cl,4
  1090.     shr     ax,cl
  1091.     mov     clustseg,ax
  1092.     mov     di,offset subchain
  1093.     @if (sect32,=,NO)
  1094.         mov     ax,ds
  1095.         mov     es,ax
  1096.         xor     bx,bx
  1097.         mov     ds,dirbuff
  1098.         @do until
  1099.             mov     ax,es:[di]
  1100.             sub     ax,2
  1101.             mov     cx,es:clustsect
  1102.             mul     cx
  1103.             add     ax,es:drvinf.datastartsector
  1104.             mov     dx,ax
  1105.             mov     ax,es:driveno
  1106.             push    bp
  1107.             push    di
  1108.             int     26h
  1109.             @if (cf,on)
  1110.                 xor     cx,cx
  1111.                 xor     dx,dx
  1112.                 jmp abort
  1113.             @ifend
  1114.             popf
  1115.             pop     di
  1116.             pop     bp
  1117.             mov     ax,ds
  1118.             add     ax,clustseg
  1119.             mov     ds,ax
  1120.             lea     di,[di+2]
  1121.             dec     cluster
  1122.         @doend (zf,on)
  1123.         pop     ds
  1124.     @else
  1125.         mov     ax,clustsect
  1126.         mov     diskaccs.rwcount,ax
  1127.         mov     ax,dirbuff
  1128.         mov     word ptr diskaccs.dskbuffer,0
  1129.         mov     word ptr diskaccs.dskbuffer+2,ax
  1130.         @do until
  1131.             mov     bx,offset diskaccs
  1132.             mov     ax,[di]             ; ディレクトリクラスタ書き込み
  1133.             sub     ax,2
  1134.             mov     cx,clustsect
  1135.             mul     cx
  1136.             add     ax,drvinf.datastartsector
  1137.             adc     dx,0
  1138.             mov     word ptr [bx].sectornum,ax
  1139.             mov     word ptr [bx].sectornum+2,dx
  1140.             mov     ax,driveno
  1141.             mov     cx,-1
  1142.             push    bp
  1143.             push    di
  1144.             int     26h
  1145.             @if (cf,on)
  1146.                 xor     cx,cx
  1147.                 xor     dx,dx
  1148.                 jmp     abort
  1149.             @ifend
  1150.             popf
  1151.             pop     di
  1152.             pop     bp
  1153.             mov     ax,clustseg
  1154.             add     word ptr diskaccs.dskbuffer+2,ax ; 次のバッファセグメント
  1155.             lea     di,[di+2]                      ; 次のクラスタ
  1156.             dec     cluster                        ; カウントダウン
  1157.         @doend (zf,on)
  1158.     @ifend
  1159.     ret
  1160. ;
  1161. writesubdirectory  endp
  1162. ;
  1163. ;------------------------------------------------------------------------------
  1164. ;
  1165. ;   dspdirname
  1166. ;       処理中ディレクトリ名を表示する
  1167. ;
  1168. ;   TYPE    near call
  1169. ;   IN      ES:DI ディレクトリ名文字列アドレス
  1170. ;   OUT     なし
  1171. ;   保存レジスタ    DS
  1172. ;
  1173. ;------------------------------------------------------------------------------
  1174. ;
  1175. dspdirname  proc
  1176. ;
  1177.     mov     ah,9        ; 処理中メッセージ表示
  1178.     mov     dx,offset procs
  1179.     int     21h
  1180. ;
  1181.     cld                             ; ディレクトリ名長さを獲得
  1182.     mov     cx,-1
  1183.     xor     ax,ax
  1184.     mov     dx,di
  1185.   repne     scasb
  1186.     not     cx
  1187.     dec     cx
  1188. ;
  1189.     push    ds                      ; ディレクトリ名表示
  1190.     mov     ax,es
  1191.     mov     ds,ax
  1192.     call    dosstdout
  1193.     pop     ds
  1194. ;
  1195.     mov     ah,2                ; 行頭への復帰
  1196.     mov     dl,0dh
  1197.     int     21h
  1198. ;
  1199.     ret
  1200. ;
  1201. dspdirname  endp
  1202. ;
  1203. ;------------------------------------------------------------------------------
  1204. ;
  1205. ;   dspmsgend
  1206. ;       処理終了メッセージを表示する
  1207. ;
  1208. ;   TYPE    near call
  1209. ;   IN      sortcount,movecount,sortproc,sweep
  1210. ;   OUT     なし
  1211. ;   保存レジスタ    ax,bx,cx,dx,si,di,bp,ds,es
  1212. ;
  1213. ;------------------------------------------------------------------------------
  1214. ;
  1215. dspmsgend   proc    uses ax bx cx dx si di ds es
  1216.         local   wrks:dword,wrka:word
  1217. ;
  1218.     mov     ax,sortcount            ; ソートしたエントリ数
  1219.     mov     bx,movecount            ; 移動したエントリ数
  1220.     mov     cx,ax
  1221.     add     cx,bx
  1222.     @cbegin
  1223.     @case (sortexec,=,YES),and,(sweep,=,YES),and,(cx,/=,0),S ; ソート&移動
  1224.         mov     ax,cx
  1225.         mov     si,offset bothmsg
  1226.     @case (sortexec,=,YES),and,(sweep,=,NO),and,(ax,/=,0),S ; ソートのみ
  1227.         @if (ax,>,1),S
  1228.             mov     si,offset sortmsg   ; 2つ以上ならソートのみ表示
  1229.         @else
  1230.             mov     si,offset bothmsg   ; 1つだけならソート&移動表示
  1231.         @ifend
  1232.     @case (sortexec,=,NO),and,(sweep,=,YES),and,(bx,/=,0),S ; 移動のみ
  1233.         mov     ax,cx
  1234.         mov     si,offset movemsg   ; 移動
  1235.     @other
  1236.         xor     ax,ax
  1237.         mov     si,offset nothmsg   ; 対象なし
  1238.     @cend
  1239.     @if (ax,/=,0)
  1240.         mov     di,ss               ; 処理したエントリ数表示
  1241.         mov     es,di
  1242.         lea     di,offset wrka+1
  1243.         call    inttoasc0
  1244.         lea     di,[di-5]           ; 0サプレス処理
  1245.         push    di
  1246.         mov     cx,4
  1247.         @do while,(byte ptr es:[di],=,'0'),and,(cx,/=,0)
  1248.             mov     byte ptr es:[di],' '
  1249.             inc     di
  1250.             dec     cx
  1251.         @doend
  1252.         mov     cx,5                ; エントリ数表示
  1253.         pop     dx
  1254.         mov     di,ds
  1255.         push    ss
  1256.         pop     ds
  1257.         call    dosstdout
  1258.         mov     ds,di
  1259.     @ifend
  1260.     mov     ah,9                    ; エントリ数に続くメッセージ表示
  1261.     mov     dx,si
  1262.     int     21h
  1263.     ret
  1264. ;
  1265. dspmsgend   endp
  1266. ;
  1267. ;------------------------------------------------------------------------------
  1268. ;
  1269. ;   altint23h
  1270. ;       Ctrl+C押下の横取り
  1271. ;
  1272. ;   TYPE    interrupt
  1273. ;   IN      なし
  1274. ;   OUT     なし
  1275. ;   保存レジスタ    ax,bx,cx,dx,si,di,bp,ds,es
  1276. ;
  1277. ;------------------------------------------------------------------------------
  1278. ;
  1279. altint23h   proc
  1280. ;
  1281.     @if (cs:critical,=,NO),S        ; クリティカルセクションではない時
  1282.         jmp     cs:orgint23h        ; 既存の終了処理へ
  1283.     @else                           ; クリティカルセクションの時
  1284.         mov     cs:breakflag,YES    ; Ctrl+C押下を記憶しただけで復帰
  1285.         iret
  1286.     @ifend
  1287. ;
  1288. altint23h   endp
  1289. ;
  1290.         end     main
  1291.